-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Deprecate Usage
in favour of RequestUsage
and RunUsage
#2378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
PR Change SummaryIntroduced a new Usage interface to enhance compatibility with the genai-prices library.
Modified Files
How can I customize these reviews?Check out the Hyperlint AI Reviewer docs for more information on how to customize the review. If you just want to ignore it on this PR, you can add the Note specifically for link checks, we only check the first 30 links in a file and we cache the results for several hours (for instance, if you just added a page, you might experience this). Our recommendation is to add |
Docs Preview
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR deprecates the old Usage
class and introduces two new classes: RequestUsage
and RunUsage
. The main purpose is to work with the genai-prices library by providing more precise usage tracking. It also renames several token-related fields for consistency.
- Deprecates
pydantic_ai.usage.Usage
in favor ofRequestUsage
(for individual model requests) andRunUsage
(for complete agent runs) - Renames token fields from
request_tokens
/response_tokens
toinput_tokens
/output_tokens
with deprecation warnings - Updates
ModelResponse
to useprovider_details
andprovider_request_id
instead ofvendor_details
andvendor_id
Reviewed Changes
Copilot reviewed 65 out of 66 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
tests/test_usage_limits.py | Updates tests to use new RequestUsage and RunUsage classes, including tests for deprecated field warnings |
tests/test_toolsets.py | Simple import update from Usage to RunUsage |
tests/test_tools.py | Updates import and usage expectations from Usage to RequestUsage |
tests/test_streaming.py | Updates imports and test assertions to use new usage classes |
tests/test_mcp.py | Updates usage assertions and model response field names throughout MCP tests |
tests/test_history_processor.py | Updates usage expectations in history processor tests |
tests/test_direct.py | Updates direct model request tests to use RequestUsage |
tests/test_agent.py | Comprehensive updates across agent tests for new usage classes and field names |
tests/test_a2a.py | Simple usage class update in agent-to-agent tests |
tests/models/test_openai_responses.py | Updates OpenAI model response tests with new usage classes and field names |
tests/models/test_openai.py | Extensive updates to OpenAI model tests for new usage tracking |
tests/models/test_model_test.py | Updates test model usage expectations |
tests/models/test_model_function.py | Updates function model tests with new usage classes |
tests/models/test_mistral.py | Updates Mistral model tests with new usage tracking and field names |
tests/models/test_mcp_sampling.py | Removes usage assertions in MCP sampling tests |
tests/models/test_instrumented.py | Updates instrumented model tests to use RequestUsage |
tests/models/test_huggingface.py | Updates HuggingFace model tests with new usage classes |
tests/models/test_groq.py | Updates Groq model tests with new usage tracking |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Usage
in favour of RequestUsage
and RunUsage
to work with genai-pricesUsage
in favour of RequestUsage
and RunUsage
class RequestUsage(UsageBase): | ||
"""LLM usage associated with a single request. | ||
|
||
This is an implementation of `genai_prices.types.AbstractUsage` so it can be used to calculate the price of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it doesn't inherit the protocol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pyright complains with things like error: "input_tokens" incorrectly overrides property of same name in class "AbstractUsage"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we use property
here as well to match it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand we don't want to delay things, but it seems weird to not use the abstract class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even genai-prices is like this with the concrete Usage
class.
these attributes are writable, so we'd need a getter and setter for each, and __init__
and __eq__
. dataclasses are too helpful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not even the one in genai-prices
use it, what's the point? Is it even type safe if you use AbstractUsage
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
functions like calc_price in genai-prices expect this protocol, and having the relevant attributes means the protocol is satisfied automatically, so e.g. RequestUsage is accepted by those functions.
Closes #2352
pydantic_ai.usage.Usage
.AgentRunResult.usage()
now returns aRunUsage
whileModelResponse.usage
is aRequestUsage
. The two classes are very similar, but prices should only be calculated using aRequestUsage
. The classes also differ slightly from the oldUsage
:request_tokens
toinput_tokens
andresponse_tokens
tooutput_tokens
with deprecation warnings. Similar renames apply to theUsageLimits
constructor.None
, they all default to0
except fordetails
which defaults to{}
.ModelResponse
:vendor_details
toprovider_details
andvendor_id
toprovider_request_id
inModelResponse
with deprecation warnings.ModelResponse.price()
method to calculate the actual cost of a single request using https://github.com/pydantic/genai-prices.ModelResponse.provider_name
field